package mws;

import jakarta.annotation.PostConstruct;

import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;


public class ThreadPoolContext {

    private final static ThreadPoolContext INSTANCE = new ThreadPoolContext();

    public static ThreadPoolContext getInstance() {
        return ThreadPoolContext.INSTANCE;
    }

    private final static Object object;
    static {
        object = new Object();
        if(INSTANCE.getThreadPoolExecutor("commonThreadPool") == null){
            synchronized (object){
                if (INSTANCE.getThreadPoolExecutor("commonThreadPool") == null) {
                    INSTANCE.setThreadPoolExecutor("commonThreadPool",ThreadPoolUtil.createThreadPoolExecutor(ThreadPoolProperty.createDefault()));
                }
            }
        }
    }

    private final ConcurrentHashMap<String, ThreadPoolExecutor> threadPoolExecutorMap = new ConcurrentHashMap<>();

    private final ConcurrentHashMap<String, ThreadPoolProperty> threadPoolPropertyMap = new ConcurrentHashMap<>();


    @PostConstruct
    public void start(){
        Runtime.getRuntime().addShutdownHook(new Thread(this::shutdown));
    }

    public ThreadPoolExecutor getThreadPoolExecutor(String threadPoolName) {

        return threadPoolExecutorMap.get(threadPoolName);
    }

     public void setThreadPoolExecutor(String threadPoolName, ThreadPoolExecutor threadPoolExecutor) {
        threadPoolExecutorMap.put(threadPoolName, threadPoolExecutor);
    }

    public ThreadPoolProperty getThreadPoolProperty(String threadPoolName) {
        return threadPoolPropertyMap.get(threadPoolName);
    }

    public void setThreadPoolProperty(String threadPoolName, ThreadPoolProperty threadPoolProperty) {
        threadPoolPropertyMap.put(threadPoolName, threadPoolProperty);
    }

    public void shutdown(){
        threadPoolExecutorMap.values().forEach(ThreadPoolExecutor::shutdown);
    }

    public Set<String> getNameSet(){
        return new HashSet<>(threadPoolPropertyMap.keySet());
    }

    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder();
        sb.append("ThreadPoolExecutorMap {\n");

        // 遍历所有线程池
        threadPoolExecutorMap.forEach((poolName, executor) -> {
            sb.append("  [线程池名称]: ").append(poolName).append("\n");
            sb.append("    核心线程数: ").append(executor.getCorePoolSize()).append("\n");
            sb.append("    最大线程数: ").append(executor.getMaximumPoolSize()).append("\n");
            sb.append("    当前活跃线程数: ").append(executor.getActiveCount()).append("\n");
            sb.append("    队列任务数: ").append(executor.getQueue().size()).append("\n");
            sb.append("    已完成任务数: ").append(executor.getCompletedTaskCount()).append("\n");
            sb.append("    总任务数: ").append(executor.getTaskCount()).append("\n");
            sb.append("    线程存活时间(秒): ").append(executor.getKeepAliveTime(TimeUnit.SECONDS)).append("\n");
            sb.append("    是否关闭: ").append(executor.isShutdown()).append("\n");
            sb.append("    是否终止: ").append(executor.isTerminated()).append("\n");
            sb.append("    拒绝策略: ").append(executor.getRejectedExecutionHandler().getClass().getSimpleName()).append("\n\n");
        });

        sb.append("}");
        return sb.toString();
    }



}
